package com.yangchuang.openpicture.service.impl;

import com.yangchuang.openpicture.communication.ResultCode;
import com.yangchuang.openpicture.constant.EmailConstants;
import com.yangchuang.openpicture.exception.BussinessException;
import com.yangchuang.openpicture.service.EmailService;
import com.yangchuang.openpicture.util.RedisUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * 邮箱服务类
 */
@Slf4j
//因为设计到具体的业务逻辑 所以使用@service
@Service
@RequiredArgsConstructor

public class EmailServiceImpl implements EmailService {


    @Value("${spring.mail.username}")
    private String fromEmail;
    private final JavaMailSender mailSender;
    private final RedisUtils redisUtils;


    /**
     * 发送邮箱验证码  并且把验证码存到到redis里面
     * key的生成策略：常量+email
     * value的值：生成的验证码
     *
     * @param email 邮箱地址
     * @return 验证码
     */
    public void sendVerifyCode(String email) {
        // 生成6位随机验证码   使用 Apache Commons Lang 的 RandomStringUtils
        String verifyCode = RandomStringUtils.random(10, true, true);
        try {
            // 发送邮件
            SimpleMailMessage message = new SimpleMailMessage();
            message.setFrom(fromEmail); // 发送方邮箱  这个从application.yml里面读取
            message.setTo(email);
            message.setSubject("邮箱验证码");
            message.setText("您的验证码是：" + verifyCode + "，有效期5分钟，请勿泄露给他人。");
            mailSender.send(message);

            // 将验证码存储到Redis，设置5分钟过期
            redisUtils.string().addWithTTL(EmailConstants.VERIFY_CODE_PREFIX + email,
                    verifyCode, EmailConstants.CODE_EXPIRE_MINUTES, TimeUnit.MINUTES);
            log.info("验证码发送成功：email={}", email);
        } catch (Exception e) {
            log.error("验证码发送失败：email={}", email, e);
            throw new RuntimeException("验证码发送失败", e);
        }
    }

    /**
     * 验证邮箱验证码 并且删除redis
     *
     * @param email 邮箱地址
     * @param code  验证码
     * @return 是否验证成功 true 验证成功 false 验证失败
     */
    public boolean verifyCode(String email, String code) {
        String key = EmailConstants.VERIFY_CODE_PREFIX + email;
        //用 相同的规则 去redis里面取出验证码 这样就确保了 一对一 不会 我和别人的验证码进行比较
        String verifycode = redisUtils.string().getValueByKey(key);
        if (verifycode == null) {
            //取不出来 说明过期了
            throw new BussinessException(ResultCode.VERIFICATION_CODE_EXPIRED);
        }
        // 不管验证码正确与否，我们都删除redis 因为已经没有意义继续存放
        redisUtils.string().deleteByKey(key);
        return verifycode.equals(code);
    }


}
